package cn.agiledata.bank.transaction.action;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.account.dao.hibernate.HibernateAccountDAO;
import cn.agiledata.bank.account.service.AccountSummary;
import cn.agiledata.bank.account.service.IAccountService;
import cn.agiledata.bank.audit.service.AuditService;
import cn.agiledata.bank.common.dao.AccountTemplateInter;
import cn.agiledata.bank.common.dao.ActionTypeTemplate;
import cn.agiledata.bank.common.dao.BankTemplate;
import cn.agiledata.bank.common.dao.TransactionTemplate;
import cn.agiledata.bank.common.service.email.GainMoneyEmail;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AccountBank;
import cn.agiledata.bank.hibernateBean.AccountLimit;
import cn.agiledata.bank.hibernateBean.EsPrePayTrans;
import cn.agiledata.bank.hibernateBean.FeeRatio;
import cn.agiledata.bank.hibernateBean.Groups;
import cn.agiledata.bank.hibernateBean.SubAccount;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.myspace.service.IMySpaceService;
import cn.agiledata.bank.transaction.audit.service.EsPrePayTransService;
import cn.agiledata.bank.transaction.form.FillMoneyForm;
import cn.agiledata.bank.transaction.service.EsPrePayTransFactory;
import cn.agiledata.bank.transaction.service.FeeForVNV;
import cn.agiledata.bank.transaction.service.FeeRatioInterf;
import cn.agiledata.bank.transaction.service.GetEsPrePayTrans;
import cn.agiledata.bank.transaction.service.GetEsPrePayTransImpl;
import cn.agiledata.bank.transaction.service.GetTransaction;
import cn.agiledata.bank.transaction.service.GetTransactionImpl;
import cn.agiledata.bank.transaction.service.TransactionFactory;
import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBAppFactory;
import com.vnv.infrastructure.logic.IPBMgrFactory;

public class TransactionActionHelper {

	static TransactionActionHelper helper = new TransactionActionHelper();

	protected IMySpaceService getMySpaceService() throws IPBException {
		return (IMySpaceService) IPBAppFactory.getObj(IMySpaceService.MGR_ID);
	}

	private TransactionActionHelper() {
	}

	public static TransactionActionHelper getTransactionActionHelper() {
		return helper;
	}

	private EsPrePayTransService getEsPrePayTransService() {
		return (EsPrePayTransService) IPBAppFactory
				.getObj("EsPrePayTransService");
	}

	private AuditService getAuditService() {
		return (AuditService) IPBAppFactory.getObj("auditService");
	}

	public synchronized ActionForward saveRemitTransaction(
			ActionMapping mapping, HttpServletRequest request,
			TransactionTemplate transactionTemplate, AccountTemplateInter at,
			FillMoneyForm fill, String actionType, String wrongString,
			String successString) throws Exception, IPBException {

		ActionForward af = mapping.findForward(wrongString);
		Transaction tran = fillTransactionWithForm(request, fill, at,
				actionType);
		tran.setTransId(fill.getTransactionId());
		tran.setPurpose(fill.getPurpose());
		// 检验支付密码(企业用户不需要验证)
		AccountSummary accountsummary = WeatherUtil
				.getLoingInfoFromSession(request);

		
		if (!accountsummary.getAccount().getAccountType().equals(
				Constant.ACCOUNT_TYPE_CORPORATION)) {
			if (!at.compareAccountPickUpPassword(tran.getDebit().getAccount(),
					fill.getPinkUpPass())) {
				fill.setErrorMsg("支付密码输入错误！");
				request.setAttribute("FillMoneyForm", fill);
				IAccountService as = (IAccountService) IPBAppFactory
						.getObj("accountService");
				request.setAttribute("BankList", as
						.getBankBySubaccountId(WeatherUtil
								.getSubAccountIdFromSession(request)));
				af = mapping.findForward(wrongString);
				return af;
			}
		}

		// 验证账户余额
		if (at.compareAccountMoney(tran.getDebit().getId().toString(), tran
				.getAmount()) != 0) {
			fill.setErrorMsg("提现操作失败您的提现金额为" + tran.getAmount() + "，提现金额不正确！");
			af = mapping.findForward(wrongString);
			return af;
		}

		/* 金额限制 */
		AccountLimit al = transactionTemplate.getAcctlimit(tran.getDebit()
				.getAccount());
		if (tran.getDebit().getAccount().getAccountType().equals(
				Constant.ACCOUNT_TYPE_BUYER)) {
			if (transactionTemplate.ifHigher(tran.getDebit().getAccount(), tran
					.getAmount().doubleValue(), al)) {
				int tranamount;
				if (tran.getDebit().getAccount().getTranAmount() == null) {
					tranamount = 0;
				} else {
					tranamount = tran.getDebit().getAccount().getTranAmount()
							.intValue();
				}
				String err = "提现操作失败，您单笔交易限制为"
						+ al.getEachlimit()
						+ "元，单天交易限制为"
						+ al.getAlllimit()
						+ "元，单天交易笔数限制为"
						+ al.getTranamount().intValue()
						+ "笔,您今天已经提现了"
						+ tranamount
						+ "笔，共"
						+ tran.getDebit().getAccount().getSumAmount()
								.doubleValue() + "元，本笔交易额为"
						+ tran.getAmount().doubleValue() + "元。本次交易超过了限制";
				fill.setErrorMsg(err);
				af = mapping.findForward(wrongString);
				return af;
			} else {
				fill.setErrorMsg("");
			}
		}

		/* 金额限制 */
		GetTransaction getTran = new GetTransactionImpl();
		TransactionFactory tt = getTran.getTransaction(actionType);
		GetEsPrePayTrans getEsPrePayTran = new GetEsPrePayTransImpl();
		EsPrePayTransFactory epptf = getEsPrePayTran.getTransaction(actionType);
		String scoresSource = null;
		if (actionType.equals(Constant.ACTION_TYPE_D))
			scoresSource = Constant.SCORES_SOURCE_C;
		if (actionType.equals(Constant.ACTION_TYPE_G))
			scoresSource = Constant.SCORES_SOURCE_F;

		try {
			// 个人用户保存交易信息
			if (!accountsummary.getAccount().getAccountType().equals(
					Constant.ACCOUNT_TYPE_CORPORATION)) {
				tt.saveTransaction(tran);
				Account acct = tran.getDebit().getAccount();
				acct.setSumAmount(new Double(acct.getSumAmount().doubleValue()
						+ tran.getAmount().doubleValue()));
				if (acct.getTranAmount() == null) {
					acct.setTranAmount(new Double(1));
				} else {
					acct.setTranAmount(new Double(acct.getTranAmount()
							.doubleValue() + 1));
				}
				getMySpaceService().updateAccount(acct);

				TransactionTemplate template = (TransactionTemplate) IPBAppFactory
						.getObj("transactionTemplate");
				GainMoneyEmail mail = (GainMoneyEmail) IPBAppFactory
						.getObj("gainMoneyMail");
				if (template.ifSendMail(tran.getDebit().getAccount(),
						Constant.GAINMONEY)) {
					if (actionType.equals(Constant.ACTION_TYPE_G)) {
						mail.setEmailTitle("您的账户直付通知");
						mail.setContentTitle("直付");
						mail.setPaytype("直付");
					} else {
						mail.setEmailTitle("您的账户提现通知");
						mail.setContentTitle("提现");
						mail.setPaytype("提现");
					}
					mail.sendMail(tran, null);
				}
				if (template.ifSendMobile(tran.getDebit().getAccount(),
						Constant.GAINMONEY)) {
					if (actionType.equals(Constant.ACTION_TYPE_G)) {
						mail.setContentTitle("账户直付");
						mail.setSmsContext("sms-drawToOther.vm");
					} else {
						mail.setEmailTitle("您的账户提现通知");
						mail.setContentTitle("提现");
					}
					mail.sendSms(tran, null);
				}
			}

			// 企业用户保存交易信息
			if (accountsummary.getAccount().getAccountType().equals(
					Constant.ACCOUNT_TYPE_CORPORATION)) {
				// 拷贝tran对象到EsPrePayTrans
				tran.setOperatorSeq(String.valueOf(accountsummary.getOperatorCode()));
				EsPrePayTrans esPPTran = new EsPrePayTrans();
				PropertyUtils.copyProperties(esPPTran, tran);
				// 判断是否需要审核
				boolean ifAudit = getAuditService().requiredUserAudit(
						accountsummary.getAccountId(),
						getAuditService().getAuditOperandType(
								"ES_PRE_PAY_TRANS",
								String.valueOf(tran.getActionType().getId())));
				if (ifAudit) {
					esPPTran.setTransStatus(Constant.ES_TRANS_STATUS_UNAUDIT);
				} else {
					esPPTran.setTransStatus(Constant.ES_TRANS_STATUS_UNPAY);
				}
				// 保存交易对象
				epptf.saveTransaction(esPPTran);
				// 保存审核对象
				if (accountsummary.getOperatorCode() != null) {
					getEsPrePayTransService()
							.submitAuditOperation(
									esPPTran,
									accountsummary
											.getOperatorByIdInstance(String
													.valueOf(accountsummary
															.getOperatorCode())));
				} else {
					getEsPrePayTransService().submitAuditAccount(esPPTran,
							accountsummary.getAccount());
				}
			}

			String email = fill.getLoginAccount().getEmail();
			String subAccountBalance = at.getSubAccount(fill.getDebitEmail())
					.getAccountId();
			String balance = new DecimalFormat("0.00").format(getSubBalance(
					email, subAccountBalance));
			request.setAttribute("AccountBalance", balance);
			af = mapping.findForward(successString);
			//
		} catch (RuntimeException e) {
			e.printStackTrace();
			fill.setErrorMsg("提现操作失败，请重新登录！");
			af = mapping.findForward("main");
		} finally {
			fill.setIfFinished(true);
		}
		return af;
	}

	private Transaction fillTransactionWithForm(HttpServletRequest request,
			FillMoneyForm fill, AccountTemplateInter at, String actionType)
			throws Exception {
		ActionTypeTemplate att = (ActionTypeTemplate) IPBMgrFactory
				.getMgr("actionTypeTemplate");

		BankTemplate bt = (BankTemplate) IPBMgrFactory.getMgr("bankTemplate");

		Transaction tran = new Transaction();
		tran.setTransStatus(Constant.TRANS_STATUS_TRANSACTIONSUCCESS);
		tran.setRemark(fill.getRemark());
		tran.setCredit(at.getRemitAccount());
		tran.setActionType(att.getActionTypeById(Long.parseLong(actionType)));
		tran.setAmount(new Double(fill.getAccount()));
		tran.setPurpose(fill.getPurpose());
		tran.setAccountBankSeq(fill.getBankType());
		if (actionType.equals(Constant.ACTION_TYPE_D)) {
			AccountBank ab = bt.getAccountBankById(String.valueOf(fill
					.getBankType()));
			tran.setCardNo(ab.getAccountId());
			tran.setBankCitySeq(ab.getCitySeq());
			tran.setBankSeq(ab.getBankInfo().getId());
			tran.setBankName(ab.getBankName());
			tran.setBankProvSeq(ab.getProvSeq());
			tran.setBankCitySeq(ab.getCitySeq());
			tran.setPersonName(ab.getAccountName());
		}
		if (actionType.equals(Constant.ACTION_TYPE_G)) {
			tran.setCardNo(fill.getCardNo());
			if (fill.getCitySeq() != null && !fill.getCitySeq().equals("")) {
				tran.setBankCitySeq(new Long(fill.getCitySeq()));
			}
			if (fill.getProvSeq() != null && !fill.getProvSeq().equals("")) {
				tran.setBankProvSeq(new Long(fill.getProvSeq()));
			}
			// 加上收款人信息 given 20070411
			tran.setBankSeq(new Long(fill.getBankType()));
			tran.setPersonName(fill.getCreditName());
			tran.setPersonMail(fill.getCreditEmail());
			tran.setPersonMobile(fill.getCreditMobile());
			tran.setPersonPhone(fill.getCreditPhone());
			tran.setBankName(fill.getOpenBank()); // 收款方开户行名称
		}

		tran.setTransId(fill.getTransactionId());
		tran.setAuditTrans("0");
		tran.setDebit(at.getSubAccount(fill.getDebitEmail()));
		FeeRatioInterf fri = (FeeRatioInterf) IPBMgrFactory.getMgr("FeeRatio");
		fill.setRatio(fri.getDebitFee(tran));

		// 封装插入日期和修改日期
		WeatherUtil.fillCreateAndUpdateInfo(tran, tran.getDebit().getAccount()
				.getId().toString());
		tran.setBeginDate(new Date());

		return tran;
	}

	public String getFeeRatio(Groups ag, String id) {
		FeeForVNV ff = (FeeForVNV) IPBMgrFactory.getMgr("FeeRatio");
		String rt;
		String fl;
		String str;

		FeeRatio fr = ff.getFeRatio(ag, id);
		if (fr == null) {
			return "优惠期间，免收手续费！";
		}
		String bDate = DateFormat.getDateInstance().format(fr.getBeginDate());
		String eDate = DateFormat.getDateInstance().format(fr.getEndDate());

		if (fr.getFeemethod().equals("1")) {
			rt = "固定收费";
			fl = fr.getFixFee().toString();
			str = ("收费方式：" + rt + " 手续费: " + fl + "元  有效期：" + bDate + " 至 " + eDate);
		} else {
			rt = "按金额比例";
			fl = fr.getRatio().toString() + "%";
			str = "收费方式：" + rt + " 费率: " + fl + " 最低收费：" + fr.getMinFee()
					+ "元  ";
			
			// zln 修正 20080326 费率上限可以为空
			if (fr.getMaxFee() != null && fr.getMaxFee().doubleValue() > 0) {
				str += "最高收费：" + fr.getMaxFee() + "元 ";
			}
			
			str += "有效期：" + bDate + " 至 " + eDate;
		}
		return str;
	}

	public Double getSubBalance(String sign, String subAccountId)
			throws Exception {
		HibernateAccountDAO had = null;
		Double ab = new Double(0);
		try {
			had = (HibernateAccountDAO) IPBAppFactory.getObj("accountDAO");
		} catch (Exception e) {
			e.printStackTrace();
		}
		Account acc = had.findAccountBySign(sign);

		List list = had.getSubAccountOfAccount(acc);
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			SubAccount sa = (SubAccount) iter.next();
			if (sa.getAccountId().equals(subAccountId.toString()))
				ab = (sa.getAccountBalance().getBalance());

		}
		return ab;

	}
}